<?php


namespace EchoPHP\Cache;

use Exception;
use EchoPHP\Foundation\Exception\HttpException;
use EchoPHP\Redis\PhpRedisConnector;
use InvalidArgumentException;

class CacheManager {

    /**
     * 应用程序容器
     * @var EchoPHP\Foundation\Application
     */
    protected $app;

    /**
     * 缓存连接
     * @var array
     */
    protected $stores = [];

    public function __construct($app) {
        $this->app = $app;
    }

    /**
     * 链接存储驱动
     * @param null $name
     * @return CacheContract
     */
    public function connect($name = null) {
        $name = $name ?? $this->getDefaultDriver();
        if (isset($this->stores[$name])) {
            return $this->stores[$name];
        }
        return $this->stores[$name] = $this->resolve($name);
    }

    /**
     * 解析缓存驱动
     * @param $name
     * @return mixed
     */
    protected function resolve($name) {
        $config = $this->app['config']['cache.stores.' . $name];
        if (is_null($config)) {
            throw new InvalidArgumentException('不支持[' . $name . ']类型的缓存存储方式');
        }
        $driverMethod = 'create' . ucfirst(strtolower($config['driver'])) . 'Driver';
        if (method_exists($this, $driverMethod)) {
            return $this->{$driverMethod}($config);
        } else {
            throw new InvalidArgumentException('缓存存储[' . $name . ']不支持[' . $config['driver'] . ']这种存储驱动');
        }
    }

    /**
     * 生成文件缓存驱动类
     * @param $config
     * @return FileStore
     */
    protected function createFileDriver($config) {
        return (new FileStore($this->app['filesystem'], $config['path']));
    }

    protected function createRedisDriver($config) {
        $connector = new PhpRedisConnector();
        try {
            $redis = $connector->connect($config['servers']);
        } catch (HttpException $e) {
            //redis链接失败
            $redis = null;
        } catch (Exception $e) {
            throw $e;
        }
        return (new RedisStore($redis));
    }

    /**
     * 生成memcache缓存存储驱动类
     * @param $config
     * @return MemcacheStore
     */
    protected function createMemcacheDriver($config) {
        $memcached = $this->app['memcached.connector']->connect(
            $config['servers'],
            $config['persistent_id'] ?? null,
            $config['options'] ?? []
        );
        $namespace = $config['namespace'] ?? '';
        $prefix = $config['prefix'] ?? '';
        return (new MemcacheStore($memcached, $namespace, $prefix));
    }

    /**
     * 获取默认缓存驱动名称
     * @return mixed
     */
    protected function getDefaultDriver() {
        return $this->app['config']['cache.default'];
    }
}